% -*- coding: utf-8 -*-
% Ada 95 品质和风格
% 版权所有 (C) 2009, 朱群英
% Copyright (C) 2009, Zhu Qun-Ying
%
% 本书的 TeX 代码和由之生成的 ps，pdf，html，等其他格式的文件
% 遵循 GNU通用公共授权第三版或其后的版本。
%
% 本书是基于有益的目的而加以发布，然而不负任何担保责任。
%
% 您应已收到附随于本书的GNU通用公共授权的副本；如果没有，
% 请参考 <http://www.gnu.org/licenses/gpl.html>

\chapter{源代码的呈现}
\label{c:src}
代码在纸张和屏幕上的版面规划对于代码的可读性起了很大的作用。本章包含了
令代码更可读的呈现准则。

在通用的准则之外，在\glemph{具体事例}部分，还有特别的推荐。如果你不同意
这些特别的推荐，你可以采用自己的规约，同时也遵守了准则。总之，保持全项目的一致。

完全一致的版面规约很难靠人工去完成和检查，所以，对于版面规范的自动化，
你可能比较细欢使用工具根据不同参数来格式化代码，或者把准则整合到自动代码
模块。某些准则和特别的推荐不能用自动格式化工具完成，因为它们是基于 Ada 语句
的语义而非语法。\glemph{自动化注解}会给出更多的详细内容。

\section{代码格式化}
代码的格式化影响代码的观感，而不是代码的功用。这里讨论的问题包括：水平间隔、
缩进、对齐、分页和行长度。最重要的准则是在编译单元和整个项目中保持一致。

\subsection{水平间隔}
\glentry{准则}
\begin{itemize}
    \item 分割符之间使用固定的间隔。
    \item 使用和写一般文章一样的空格。
\end{itemize} 


\glentry{具体事例}
\begin{blockindent}
特别指出，在下列地方，保留至少一个空格，本书中的范例也使用
一样的准则。紧跟的准则会为了对齐的原因，可能需要更多的纵向空间。
    \begin{itemize}
	\item[-] 在下列分隔符和二进制操作符的前后：
	    \begin{quote}
	    \texttt{
	    \begin{tabular}[h]{l l l l l l l l l l l l}
		+  & & -  & & * & & /  & & \& \\
		<  & & =  & & > & & /= & & <= & >=\\
		:= & & => & & | & & .. \\
		: \\
		<>\\
	    \end{tabular}
	    }
	    \end{quote}
	\item[-] 除了禁止的地方，在字符串和字符引号(\texttt{"}) 和
(\texttt{'})之外的文字。
	\item[-] 在括号的外面，不是里面。
	\item[-] 在逗号 (,) 和 分号 (;) 之后。
    \end{itemize}
在下列的地方不要有任何空格，即使和上面的建议相背。
    \begin{itemize}
	\item[-] 当加号(+)和减号($-$)作为一元操作符时，它们的后面。
	\item[-] 函数调用的后面。
	\item[-] 在标签分隔符内 (\texttt{<< >>})。
	\item[-] 在幂操作符(\texttt{**})、撇号(\texttt{'})和句号(.)的前后。
	\item[-] 在多个连续的开启或终止括号中间。
	\item[-] 在逗号 (,) 和 分号 (;) 之前。
    \end{itemize}
当多余的括号因为操作优先的规则被忽略，表达式中围绕最高优先级
操作符的空格可选择性的去除。

\end{blockindent}


\glentry{范例}
\begin{blockindent}
\begin{lstlisting}
Default_String : constant String :=
      "This is the long string returned by" &
      " default. It is broken into multiple" &
      " Ada source lines for convenience.";

type Signed_Whole_16 is range -2**15 .. 2**15 - 1;
type Address_Area  is array (Natural range <>) of Signed_Whole_16;

Register : Address_Area (16#7FF0# .. 16#7FFF#);
Memory   : Address_Area (       0 .. 16#7FEC#);

Register(Pc) := Register(A);

X := Signed_Whole_16(Radius * Sin(Angle));

Register(Index) := Memory(Base_Address + Index * Element_Length);

Get(Value => Sensor);

Error_Term := 1.0 - (Cos(Theta)**2 + Sin(Theta)**2);

Z      := X**3;
Y      := C * X + B;
Volume := Length * Width * Height;
\end{lstlisting}

\end{blockindent}

\glentry{原理}
\begin{blockindent}
分隔符和操作符通常只有一到两个字符的宽度，很容易在比较长的关键字和变量名
中迷失，所以在它们周围加上空格是很好的注意。这让它们突出。代码中一致的空格
也有助于视觉上的审视。

但是，许多分隔符(逗号、分号、括号，等)是我们熟悉的普通标点符号。如果电脑程序
代码中这些符号和一般的文本不一样，这很容易分散注意力。因此，使用和普通文本
一样的空格规则 (在逗号、分号前没空格，括号内内空格，等等)。

\end{blockindent}

\glentry{异例}
\begin{blockindent}
唯一引人注目的异例是冒号 (:)。在 Ada 中，有时用它来做定位符或纵列分隔符
(参见准则\ref{s:src:decl-align})，在这种情形下，在它的前面和后面加入空格而不只是
象普通文本那样加在后面，就显得有意义。
\end{blockindent}

\glentry{自动化注解}
\begin{blockindent}
本节里的准则很容易通过一个自动的代码格式器来实施。
\end{blockindent}

\subsection{缩进}
\glentry{准则}
\begin{itemize}
    \item 缩进和对齐嵌套控制结构、连续行和嵌入单元，并保持一致。
    \item 区分连续行和嵌套控制结构的缩进。
    \item 使用空格作为缩进符，不要使用标记符 (tab 字符\cite{nissen84}
\S{}2.2)。
\end{itemize}

\glentry{具体事例}
\begin{blockindent}
特别说明，推荐使用以下的缩进约定，本书中的范例都会使用。注意说明的最小缩进
空间。紧跟的准则可能需要更多的纵向空间。
\begin{itemize}
    \item[-] 使用\cite{arm95} \S{}1.1.4 中推荐的分段法
\footnote{\url{http://www.adaic.com/standards/95lrm/html/RM-1-1-4.html}}。
    \item[-] 用3个空格作为嵌套的缩进的单位。
    \item[-] 用2个空格作为连续行的缩进单位。
\end{itemize}
标签用3个空格来缩进：
\begin{lstlisting}
    begin
    <<lable>>                     | <long statement with line break>
       <statement>                |   <trailing part of same statement>
    end;
\end{lstlisting}
if和简单循环语句：
\begin{lstlisting}
    if <condition> then           | <name>:
       <statements>               |    loop
    elsif <condition> then        |       <statements>
       <statements>               |       exit when <condition>;
    else                          |       <statements>
       <statements>               |    end loop <name>;
    end if;
\end{lstlisting}
for和while循环：
\begin{lstlisting}
    <name>:                       | <name>:
       for <scheme> loop          |    while <condition> loop
          <statemetns>            |       <statements>
       end loop <name>;           |    end loop <name>;
\end{lstlisting}
语句段落块和case语句，正如\cite{arm95}中所推荐的：
\begin{lstlisting}
    <name>:			  | case <expression> is
       declare			  |    when <choice> =>
	  <declarations>	  |	  <statements>
       begin			  |    when <choice> =>
	  <statements>		  |	  <statements>
       exception		  |    when others =>
	  when <choice> =>	  |	  <statements>
	     <statements>	  | end case; -- <comment>
	  when others =>	  |
	     <statements>	  |
       end <name>;		  |
\end{lstlisting}
下面的case语句比\cite{arm95}的推荐节省一些空间，它依赖于较短的
语句。无论你选择那种方式，要保持一致:
\begin{lstlisting}
    case <expression> is          | case <expression> is
    when <choice> =>              |    when <choice> => <statements>
	 <statements>             |                     <statements>
    when <choice> =>              |    when <choice> => <statements>
	 <statements>             |    when others   => <statements>
    when others =>                | end case;
	 <statements>             |
    end case;                     |
\end{lstlisting}
各种形式的可选accept、计时和有条件导入(entry)调用:
\begin{lstlisting}
    select                        | select
       when <guard> =>            |    <entry call>;
          <accept statement>      |    <statements>
          <statements>            | or
    or                            |    delay <interval>;
       <accept statement>         |    <statements>
       <statements>               | end select;
    or                            |
       when <guard> =>            | select
          delay <interval>;       |    <entry call>;
          <statements>            |    <statements>
    or                            | else
       when <guard> =>            |    <statements>
          terminate;              | end select;
    else                          |
       <statements>               | select
    end select;                   |    <triggering alternative>
                                  | then abort
                                  |    <abortable part>
                                  | end select;
\end{lstlisting}
accept语句:
\begin{lstlisting}
    accept <specification> do     | separate (<parent  unit>)
       <statements>               | <proper body>
    end <name>;                   |
\end{lstlisting}
一个子单元：
\begin{lstlisting}
    separate (<parent unit>)
    <proper body>
    end <name>;
\end{lstlisting}
程序单元的适当形式：
\begin{lstlisting}
    procedure <specification> is  | package body <name> is
       <declarations>             |    <declarations>
    begin                         | begin
       <statements>               |    <statements>
    exception                     | exception
       when <choice> =>           |    when <choice>=>
          <statements>            |       <statements>
    end <name>;                   | end <name>;
                                  |
    function <specification>      | task body <name> is
      return <type name> is       |    <declarations>
       <declarations>             | begin
    begin                         |    <statements>
       <statements>               | exception
    exception                     |    when <choice>=>
       when <choice> =>           |       <statements>
          <statements>            | end <name>;
    end <name>;                   |
\end{lstlisting}
编译单元的语境语句使用列表形式。通用(generic)行参不可以模糊
单元本身。对函数、封包(pacakage)和任务(task)的规约使用标准缩进:
\begin{lstlisting}
    with <name>; use <name>;      | function <specification>
    with <name>;                  |   return <type>;
    with <name>;                  |
                                  | package <name> is
                                  |    <declarations>
                                  | private
    <compilation unit>            |    <declarations>
                                  | end <name>;
                                  |
    generic                       | task type <name> is
       <formal parameters>        |    <entry declarations>
    <compilation unit>            | end <name>;

\end{lstlisting}
通用单元的实现和结构的缩进：
\begin{lstlisting}
    procedure <name> is             |type ... is
       new <generic name> <actuals> |   record
                                    |      <component list>
    function <name> is              |      case <discriminant name> is
      new <generic name> <actuals>  |          when <choice> =>
                                    |             <component list>
    package <name> is               |          when <choice> =>
       new <generic name> <actuals> |             <component list>
                                    |      end case;
                                    |   end record;
\end{lstlisting}
for结构的对齐缩进：
\begin{lstlisting}
    for <name> use
       record <mod clause>
          <component clause>
       end record;
\end{lstlisting}
标签类型和类型的扩展：
\begin{lstlisting}
    type ... is tagged
       record
          <component list>
       end record;

    type ... is new ... with
       record
          <component list>
       end record;
\end{lstlisting}
\end{blockindent}

\glentry{范例}
\begin{blockindent}
\noindent
\begin{lstlisting}
Default_String : constant String :=
      "This is the long string returned by" &
      " default. It is broken into multiple" &
      " Ada source lines for convenience.";
   if Input_Found then
      Count_Characters;
   else -- not Input_Found
      Reset_State;
      Character_Total :=
        First_Part_Total * First_Part_Scale_Factor +
        Second_Part_Total * Second_Part_Scale_Factor +
        Default_String'Length + Delimiter_Size;
   end if;
end loop;
\end{lstlisting}
\end{blockindent}

\glentry{原理}
\begin{blockindent}
缩进是程序结构的可见标示，从而提高了代码的可读性。嵌套的层数由缩进
可清晰的分辨出来，结构中开始和结束的关键字可视觉的匹配。

尽管有许多关于用多少空格来缩进的讨论，缩进的目的是令代码清晰。代码
缩进的一致比使用多少空格来缩进更重要。

另外，\cite{arm95}\S{}1.1.4 陈述推荐使用手册的例子和语法规则中用的版面规划
作为 Ada 程序的代码版面规划:``语法规则中描述的结构的构建，使用的是推荐的
分段法 …… 如果语法规则中的构建需要在不同的行上，构建会分行处理 …… 推荐所有的
缩进使用基本缩进单元的倍数(基本单元中空格的数目没有定义)。''

特别注意对连续行使用和嵌套控制结构不一样的缩进，这样它们会凸显出来，从而在
审视代码时，不会朦胧了代码结构。

语境语句列在不同的行使维护更加容易; 改变语境语句也不容易出错。

使用空格来缩进比用标记符来得易移植，因为标记符在不同的终端和打印机可能显示
不同。
\end{blockindent}

\glentry{异例}
\begin{blockindent}
如果你用变宽的字体，标记符比空格对齐的好。但是，依赖于你的标记符设置，相继
的缩进行可能只留给你很短的长度。
\end{blockindent}

\glentry{自动化注解}
\begin{blockindent}
本节里的准则很容易通过一个自动代码格式器来实施。
\end{blockindent}

\subsection{操作符的对齐}
\glentry{准则}
\begin{itemize}
    \item 竖向对齐操作符，以突出当前程序结构和语意。
\end{itemize}

\glentry{范例}
\begin{blockindent}
\noindent
\begin{lstlisting}
if Slot_A >= Slot_B then
   Temporary := Slot_A;
   Slot_A    := Slot_B;
   Slot_B    := Temporary;
end if;
----------------------------------------------------------------
Numerator   := B**2 - 4.0 * A * C;
Denominator := 2.0 * A;
Solution_1 := (B + Square_Root(Numerator)) / Denominator;
Solution_2 := (B - Square_Root(Numerator)) / Denominator;
----------------------------------------------------------------
X := A * B +
     C * D +
     E * F;
Y := (A * B + C) +  (2.0 * D - E) -  -- basic equation
     3.5;                            -- account for error factor
\end{lstlisting}
\end{blockindent}

\glentry{原理}
\begin{blockindent}
对齐使得操作符的位置更容易被看到，从视觉上强调了代码在干什么。

在长表达式中换行和间隔，突出了条件、操作符的优先级和其它语意。它也
为在表达式中标示注释留出了空间。
\end{blockindent}

\glentry{异例}
\begin{blockindent}
如果竖向对齐使得一个语句被迫变成两行，特别是如果换行的地方并不合适,
可以适当的放宽这条对齐的准则。
\end{blockindent}

\glentry{自动化注释}
\begin{blockindent}
前面的范例中，呈现一种``语意对齐''，通常自动代码格式器并不能做到或者
保留。如果你根据语意把一个表达式分拆成多个部分，每个部分各占一行，
以后使用自动代码格式器是要注意。整个表达式有可能变成一行，而注释都
集中在后面。但是，如果那一行含有注释，某些足够聪明的格式器会保留换行。
一个好的格式器可以识别出前面的范例没有违反准则，从而保留原样。
\end{blockindent}

\subsection{声明的对齐}
\label{s:src:decl-align}
\glentry{准则}
\begin{itemize}
    \item 用竖向对齐来使声明更可读。
    \item 每行最多只提供一个声明。
    \item 缩进在同一层声明部分的声明。
\end{itemize}

\glentry{具体事例}
\begin{blockindent}
对于没有被空行分隔的声明，请遵守下面的规则:
    \begin{itemize}
	\item[-] 对齐冒号分隔符。
	\item[-] 对齐初始化分隔符 \texttt{:=}。
	\item[-] 有句末注释时，对齐注释符。
	\item[-] 当声明超出了一行，注意换行以及缩进被换行。换行的地方依次
为： (1) 注释符; (2) 初始化分隔符; (3) 冒号分隔符。
	\item[-] 对于无法在一行内完成的枚举类型，让每一个字面值占一行
并缩进一级。当合适的时候，语意相关的字面值可以按行和列进行布置成为表格。
    \end{itemize}
\end{blockindent}

\glentry{范例}
\begin{blockindent}
变量和常量的声明可以按\texttt{:}、\texttt{:=}和\texttt{--}进行分隔列表\\
\begin{lstlisting}
Prompt_Column : constant        := 40;
Question_Mark : constant String := " ? "; -- prompt on error input
Prompt_String : constant String := " ==> ";
\end{lstlisting}
如果这样令行太长，可以让每以部分分占一行，同时有自己唯一的缩进级别:
\begin{lstlisting}
subtype User_Response_Text_Frame is String (1 .. 72);
-- If the declaration needed a comment, it would fit here.
Input_Line_Buffer : User_Response_Text_Frame
       := Prompt_String &
          String'(1 .. User_Response_Text_Frame'Length -
                       Prompt_String'Length => ' ');
\end{lstlisting}
枚举类型的声明，字面值可以用单列或多列成表:
\begin{lstlisting}
type Op_Codes_In_Column is
      (Push,
       Pop,
       Add,
       Subtract,
       Multiply,
       Divide,
       Subroutine_Call,
       Subroutine_Return,
       Branch,
       Branch_On_Zero,
       Branch_On_Negative);
\end{lstlisting}
或节省空间:
\begin{lstlisting}
type Op_Codes_Multiple_Columns is
      (Push,            Pop,               Add,
       Subtract,        Multiply,          Divide,
       Subroutine_Call, Subroutine_Return, Branch,
       Branch_On_Zero,  Branch_On_Negative);
\end{lstlisting}
或突出相互关系的组别:
\begin{lstlisting}
type Op_Codes_In_Table is
      (Push,            Pop,
       Add,             Subtract,          Multiply,          Divide,
       Subroutine_Call, Subroutine_Return,
       Branch,          Branch_On_Zero,    Branch_On_Negative);
\end{lstlisting}
\end{blockindent}

\glentry{原理}
许多编程标准的文档，要求在单元前的注释中用表格的形式重复名字、类型、
初始值和意义。这些注释是多余的，而且会变得和代码不符。将声明本身对齐
为表格形式 (参见之前的范例)，为编译器和读者提供了同样的信息；执行每行
最多只有一个声明；为初始化加空间和必要的注释以方便维护。表格化的版面
增强可读性，避免名字在大量的声明中``隐藏''起来。这些对所有的声明都有效:
类型、子类型、对象、异常、数字命名等等。

\glentry{自动化注解}
\begin{blockindent}
本小节中的大部分准则都可以用自动代码格式器来实施。唯一的异例是范例中
的枚举类型，它是根据字面值的语意来换行排版的。一个自动代码格式器不能
做到，很可能会把枚举类型的字面值换到不同的行。但是，只是检查是否有违规
的工具应该接受这种表格形式的枚举类型声明。
\end{blockindent}

\subsection{更多对齐}
\glentry{准则}
\begin{itemize}
    \item 竖向对齐形参模式和括号。
\end{itemize}

\glentry{具体事例}
\begin{blockindent}
特别推荐：
\begin{itemize}
    \item[-] 每行只放一个形式参数的规约。
    \item[-] 竖向对齐形参的名字、冒号、保留字 in、保留字 out 和形参的类型。
    \item[-] 把第一个形参放在子程序或入口名字的同一行。如果任何一个形参的类型
超过了行长度限制，把第一个形参放在新的一行，并使用和连续行一样的缩进。
\end{itemize}
\end{blockindent}

\glentry{范例}
\begin{blockindent}
\noindent
\begin{lstlisting}
procedure Display_Menu (Title   : in     String;
                        Options : in     Menus;
                        Choice  :    out Alpha_Numerics);
\end{lstlisting}
下面的两个例子用本准则的另外的具体事例:
\begin{lstlisting}
procedure Display_Menu_On_Primary_Window
      (Title   : in     String;
       Options : in     Menus;
       Choice  :    out Alpha_Numerics);
\end{lstlisting}
或：
\begin{lstlisting}
procedure Display_Menu_On_Screen (
       Title   : in     String;
       Options : in     Menus;
       Choice  :     out Alpha_Numerics
    );
\end{lstlisting}
对齐括号令复杂的关系表达式更加清晰：
\begin{lstlisting}
if not (First_Character in Alpha_Numerics and then
        Valid_Option(First_Character))        then
\end{lstlisting}
\end{blockindent}

\glentry{原理}
\begin{blockindent}
这个准则促进可读性和理解性，也很容易由自动化工具达到。形参模式的对齐，产生了一个
列表的效果，形参的名字、模式、类型、如果由必要，针对形参的注释。跨越同一编译单元
内子程序的竖向对齐进一步增进了可读性。
\end{blockindent}

\glentry{注解}
\begin{blockindent}
字程序的版面布局有许多可用的选择。上面的第二个例子对齐了所有子程序的形参名字。
这样有个占用不需要行的缺点，如果子程序的名字比较短，只有一个形参，那看齐来难看，

第三个例子的格式，通常用来减少形参被增加、删除或重组时需要的编辑。国号不需要随着
行来变化。但是，最后一个形参行是唯一没有冒号的。
\end{blockindent}

\glentry{异例}
\begin{blockindent}
当一个操作符函数由两个以上同类型形参，在一行里列表声明形参比把形参分到不同行里
更易读。
\begin{lstlisting}
type Color_Scheme is (Red, Purple, Blue, Green, Yellow, White, Black, Brown,
		      Gray, Pink);
function "&" (Left, Right : Color_Scheme) return Color_Scheme;
\end{lstlisting}
\end{blockindent}

\glentry{自动化注解}
\begin{blockindent}
本小节中的大部分准则都可以用自动代码格式器来实施。唯一的异例是最后一个范例中，
用竖向对齐括号来突出表达式的条件。用自动代码格式器很难做到，除非相关的条件可以
严格按照操作符的优先级来决定。
\end{blockindent}

\subsection{空行}
\glentry{准则}
\begin{itemize}
    \item 用空行来办逻辑上相关的文字组在一起 (\cite{nasa87})。
\end{itemize}

\glentry{范例}
\begin{blockindent}
\noindent
\begin{lstlisting}
if ... then

   for ... loop
      ...
   end loop;

end if;
\end{lstlisting}
这个例子把不同的类型声明用空行分割开来:
\begin{lstlisting}
type Employee_Record is
   record
      Legal_Name    : Name;
      Date_Of_Birth : Date;
      Date_Of_Hire : Date;
      Salary        : Money;
   end record;

type Day is
  (Monday,    Tuesday,   Wednesday, Thursday, Friday,
   Saturday,  Sunday);

subtype Weekday is Day range Monday   .. Friday;
subtype Weekend is Day range Saturday .. Sunday;
\end{lstlisting}
\end{blockindent}

\glentry{原理}
\begin{blockindent}
当空行在深思熟虑以及一致的情况下用时，相关的代码部分对于读者更明显。
\end{blockindent}

\glentry{自动化注解}
\begin{blockindent}
自动格式器并不能很好的实施这个准则，因为在决定在哪里插入空行和语意相关。
怠驶，许多格式器能够保留以存在的空行，所以你可以手动加入空行，当你运行
那样的格式器的时候，不会丢失你的改动。
\end{blockindent}

\subsection{分页}
\label{c:src:code_fmt:page}
\glentry{准则}
\begin{itemize}
    \item 标示每一个封包或任务规约的顶端，每个程序单元主体的顶端，和每个程序单元
的末段。
\end{itemize}

\glentry{具体事例}
\begin{blockindent}
特别推荐：
\begin{itemize}
    \item[-] 用文件序言，规约标题，和体标题来标示那些\ref{s:read:comment}中推荐的
结构。
    \item[-] 用当前缩进同一列开始的划行，来标示在声明部分嵌套的单元定义。
在定义之前和之后立即插入划行。
    \item[-] 如果两个换行相邻，忽略较长的那个。
\end{itemize}
\end{blockindent}

\glentry{范例}
\begin{blockindent}
\noindent
\begin{lstlisting}
with Basic_Types;

package body SPC_Numeric_Types is

...

    ---------------------------------------------------------------------
    function Max
	  (Left  : in    Basic_Types.Tiny_Integer;
	   Right : in    Basic_Types.Tiny_Integer)
	  return Basic_Types.Tiny_Integer is
    begin
       if Right < Left then
          return Left;
       else
          return Right;
       end if;
    end Max;

    ---------------------------------------------------------------------
    function Min
	  (Left  : in    Basic_Types.Tiny_Integer;
	   Right : in    Basic_Types.Tiny_Integer)
	  return Basic_Types.Tiny_Integer is
    begin
       if Left < Right then
          return Left;
       else
          return Right;
       end if;
    end Min;

    ---------------------------------------------------------------------

    use Basic_Types;

begin -- SPC_Numeric_Types
   Max_Tiny_Integer := Min(System_Max, Local_Max);
   Min_Tiny_Integer := Max(System_Min, Local_Min);
   -- ...
end SPC_Numeric_Types;
\end{lstlisting}
\end{blockindent}

\glentry{原理}
\begin{blockindent}
不在当前页或屏幕的程序单元很容易被忽略。呈现用的硬件和软件之间，
页长度变化很大。清楚的标示出程序逻辑页的边界(例如用划行)，读者
可以快速的检查是否整个程序单元都可见。这样的分页，也更容易在大文件中，
快速扫描到某个程序单元。
\end{blockindent}

\glentry{注解}
\begin{blockindent}
本准则不是针对物理的``页'',因为那样的页的尺寸变化很多，没有一个单一准则
可以适用。
\end{blockindent}

\glentry{自动化注解}
\begin{blockindent}
本节里的准则很容易通过一个自动代码格式器来实施。
\end{blockindent}

\subsection{每一行里的语句个数}
\glentry{准则}
\begin{itemize}
    \item 用新的一行开始每个语句。
    \item 每行不要些超过一个简单语句。
    \item 断开复合语句到多行。
\end{itemize}

\glentry{范例}
\begin{blockindent}
用：
\begin{lstlisting}
if End_Of_File then
   Close_File;
else
   Get_Next_Record;
end if;
\end{lstlisting}
不要用：
\begin{lstlisting}
if End_Of_File then Close_File; else Get_Next_Record; end if;
\end{lstlisting}
异例情况：
\begin{lstlisting}
Put("A="); Natural_IO.Put(A); New_Line;
Put("B="); Natural_IO.Put(B); New_Line;
Put("C="); Natural_IO.Put(C); New_Line;
\end{lstlisting}
\end{blockindent}

\glentry{原理}
\begin{blockindent}
每行一个语句增强了读者找到某些语句的能力，有助于避免漏了某些语句。同样的，
如果复合语句的构件在不同的行上，它的结构更清晰。
\end{blockindent}

\glentry{注解}
\begin{blockindent}
如果一个语句比一行里剩下的空间要长，在下一行继续。本准则适用于声明、语境子句
和子程序形参。

据\cite{arm95}\S{}1.1.4 描述``最好在分号之后换行。''
\end{blockindent}

\glentry{自动化注解}
\begin{blockindent}
本节里的准则很容易通过一个自动代码格式器来实施。唯一的异例是最后那个例子，
呈现了多个语句在语意组合成一行。
\end{blockindent}

\glentry{异例}
\begin{blockindent}
Put 和 New\_Line 语句的例子，呈现了一个合理的异例。把这些有紧密关系的语句
组合在一行，使组之间的结构关系更清晰。
\end{blockindent}

\subsection{源代码行长度}
\glentry{准则}
\begin{itemize}
    \item 坚持一个源代码的最大行长度 (\cite{nissen84} \S{}2.3)。
\end{itemize}

\glentry{具体事例}
\begin{blockindent}
特别推荐：
\begin{itemize}
    \item[-] 用72个字符作为行长度的最大值。
\end{itemize}
\end{blockindent}

\glentry{原理}
\begin{blockindent}
当把Ada程序从一个系统移植到另一个系统，对于源代码的语句行可能有记录的限制，
可能的原因有：某些操作系统的磁带输入输出可能不支持变长的记录，或者某些
80列的打印机或终端不支持换行。更多的原理参见准则
\ref{s:portability:global-assum}。

由于各种原因，有可能需要发行源代码，纸张对于可用的列没有电脑那样宽容。

另外，阅读代码时，人本身对理解视野内的代码也有宽度的局限，这个局限大概
在70到80列之间。
\end{blockindent}

\glentry{异例}
\begin{blockindent}
也可以用79个字符作为代码的行长度限制。79个字符宽度使得代码和 FORTAN 的
72个字符限制区分开来。它也避免了某些80列的终端对最后一列的显示问题。
\end{blockindent}

\glentry{自动化注解}
\begin{blockindent}
本节里的准则很容易通过一个自动代码格式器来实施。
\end{blockindent}

\section{总结}
\glentry{代码格式化}
\begin{itemize}
    \item 分割符之间使用固定的间隔。
    \item 使用和写一般文章一样的空格。
    \item 缩进和对齐嵌套控制结构、连续行和嵌入单元，并保持一致。
    \item 区分连续行和嵌套控制结构的缩进。
    \item 使用空格作为缩进符，不要使用标记符 (tab 字符\cite{nissen84}
    \item 竖向对齐操作符，以突出当前程序结构和语意。
    \item 用竖向对齐来使声明更可读。
    \item 每行最多只提供一个声明。
    \item 缩进在同一层声明部分的声明。
    \item 竖向对齐形参模式和括号。
    \item 用空行来办逻辑上相关的文字组在一起 (\cite{nasa87})。
    \item 标示每一个封包或任务规约的顶端，每个程序单元主体的顶端，和每个程序单元
的末段。
    \item 用新的一行开始每个语句。
    \item 每行不要些超过一个简单语句。
    \item 断开复合语句到多行。
    \item 坚持一个源代码的最大行长度 (\cite{nissen84} \S{}2.3)。
\end{itemize}

